from __future__ import absolute_import
import logging
from forest.api import Command, get_tool
import re

#from pkgr.pkgr import Pkgr
from forest.resources.packages import PackageInstallList

logger = logging.getLogger('commands.pkgr.removes')

import rpm
import glob
import os
import fnmatch

class PackageContent(object):

    def __init__(self, root):
        self.ts = rpm.TransactionSet(root)
        self.ts.initDB()
        self.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
        self.root = root

    def remove_files(self, pkg, globs):
        # calculate matches
        filelist = self.all_files(pkg)

        matches = set()
        for g in globs:
            if isinstance(g, basestring):
                globs_re = re.compile(fnmatch.translate(g))
            else:
                globs_re = g

            m = filter(globs_re.match, filelist)

            if m:
                matches.update(m)
            else:
                logger.debug("removefrom %s %s: no files matched!" % (pkg, globs_re.pattern))

        #invert match?
        #keepmatches = kwargs.get('exclusion_match', False)
        #if keepmatches:
        #    remove = filelist.difference(matches)
        #else:
        #    remove = matches

        # remove the files


        #cmd = "%s %s" % (pkg, " ".join(globs)) # save for later logging
        logger.debug("Removing %i of %i files, from pkg: %s", len(matches), len(filelist), pkg)

        for f in matches:
            #print "Remove %s" % g
            #for f in glob.glob(g):
                #print "Removing file %s" % f
                #TOOLS['system.remove'](f)
            get_tool('system.remove')(os.path.join(self.root, *f.split('/')))

        if not matches:
            logger.debug("no files to remove in pkg %s!", pkg)

    def all_files(self, pkg):
        mi = self.ts.dbMatch()
        mi.pattern('name', rpm.RPMMIRE_GLOB, pkg)

        files = []
        for header in mi:
            for prov in header[rpm.RPMTAG_FILENAMES]:
                    files.append(prov)

        return set(files)

class Removes(Command):
    __register__ =  'commands.pkgr.Removes'

    def run(self, config):
        #pkgr = config.get('_pkgr')
        #pool = pkgr.get_solv_pool()
        #installtree = config.get_install_root()
        #repos = pkgr.get_configured_repos()


        logger.debug('Removing files from packages...')

        installtree = config.get_install_root()
        config['_yum'] =  pc = PackageContent(installtree)

        package_actions = PackageInstallList(config)

        for packageaction in package_actions:
            if not packageaction.get_removes():
                continue
            pc.remove_files(packageaction.get_name(),  packageaction.get_removes())


            #logger.info(packageaction)
